package parser8051;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.util.List;
import java.util.ArrayList;
import symulator8051.Utils;
import symulator8051.memory8051;

/**
 *
 * @author Darek
 */
public class Interpreter8051 {

    public List<Instruction> instructionList = new ArrayList();
	memory8051 mem = memory8051.getInstance();
	int pc = 0;
	
    public Interpreter8051() {
    }

    public void addInstruction(String name, String[] args) {
	instructionList.add(new Instruction(name, args));
    }

    public void readInstructionList(){
        for(Instruction i : instructionList)
        {
          System.out.println(i.toString()+'\n');
	}
    }
	
	public int performNextInstruction(){
		
		if(pc == instructionList.size()){
			return instructionList.size() - 1;
		}
		
		Instruction i = instructionList.get(pc);
		
		if(i.name.equals("COPYHEXTOREG")){
			short val = Utils.getValueFromHex(i.arguments[1]);
			
			if(i.arguments[0].equals("R0")){
				mem.set(mem.R0_1, val);
			}
			
			if(i.arguments[0].equals("R1")){
				mem.set(mem.R1_1, val);
			}
			
			if(i.arguments[0].equals("R2")){
				mem.set(mem.R2_1, val);
			}
			
			if(i.arguments[0].equals("R3")){
				mem.set(mem.R3_1, val);
			}
			
			if(i.arguments[0].equals("R4")){
				mem.set(mem.R4_1, val);
			}
			
			if(i.arguments[0].equals("R5")){
				mem.set(mem.R5_1, val);
			}
			
			if(i.arguments[0].equals("R6")){
				mem.set(mem.R6_1, val);
			}
			
			if(i.arguments[0].equals("R7")){
				mem.set(mem.R7_1, val);
			}
		}
		
		else if(i.name.equals("COPYHEXTOACC")){
			short val = Utils.getValueFromHex(i.arguments[0]);
			
			mem.set(memory8051.ACC, val);
		}
		
		else if(i.name.equals("COPYFROMREGTOREG")){
			short val = 0;
			
			if(i.arguments[1].equals("R0")){
				val = mem.mem[mem.R0_1];
			}
			
			if(i.arguments[1].equals("R1")){
				val = mem.mem[mem.R1_1];
			}
			
			if(i.arguments[1].equals("R2")){
				val = mem.mem[mem.R2_1];
			}
			
			if(i.arguments[1].equals("R3")){
				val = mem.mem[mem.R3_1];
			}
			
			if(i.arguments[1].equals("R4")){
				val = mem.mem[mem.R4_1];
			}
			
			if(i.arguments[1].equals("R5")){
				val = mem.mem[mem.R5_1];
			}
			
			if(i.arguments[1].equals("R6")){
				val = mem.mem[mem.R6_1];
			}
			
			if(i.arguments[1].equals("R7")){
				val = mem.mem[mem.R7_1];
			}
			// ------
			if(i.arguments[0].equals("R0")){
				mem.set(mem.R0_1, val);
			}
			
			if(i.arguments[0].equals("R1")){
				mem.set(mem.R1_1, val);
			}
			
			if(i.arguments[0].equals("R2")){
				mem.set(mem.R2_1, val);
			}
			
			if(i.arguments[0].equals("R3")){
				mem.set(mem.R3_1, val);
			}
			
			if(i.arguments[0].equals("R4")){
				mem.set(mem.R4_1, val);
			}
			
			if(i.arguments[0].equals("R5")){
				mem.set(mem.R5_1, val);
			}
			
			if(i.arguments[0].equals("R6")){
				mem.set(mem.R6_1, val);
			}
			
			if(i.arguments[0].equals("R7")){
				mem.set(mem.R7_1, val);
			}
		}
		
		else if(i.name.equals("COPYFROMREGTOACC")){
			short val = 0;
			
			if(i.arguments[0].equals("R0")){
				val = mem.mem[mem.R0_1];
			}
			
			if(i.arguments[0].equals("R1")){
				val = mem.mem[mem.R1_1];
			}
			
			if(i.arguments[0].equals("R2")){
				val = mem.mem[mem.R2_1];
			}
			
			if(i.arguments[0].equals("R3")){
				val = mem.mem[mem.R3_1];
			}
			
			if(i.arguments[0].equals("R4")){
				val = mem.mem[mem.R4_1];
			}
			
			if(i.arguments[0].equals("R5")){
				val = mem.mem[mem.R5_1];
			}
			
			if(i.arguments[0].equals("R6")){
				val = mem.mem[mem.R6_1];
			}
			
			if(i.arguments[0].equals("R7")){
				val = mem.mem[mem.R7_1];
			}
			
			mem.set(memory8051.ACC, val);
		}
		
		else if(i.name.equals("COPYFROMACCTOREG")){
			short val = mem.get(mem.ACC);
			
			if(i.arguments[0].equals("R0")){
				mem.set(mem.R0_1, val);
			}
			
			if(i.arguments[0].equals("R1")){
				mem.set(mem.R1_1, val);
			}
			
			if(i.arguments[0].equals("R2")){
				mem.set(mem.R2_1, val);
			}
			
			if(i.arguments[0].equals("R3")){
				mem.set(mem.R3_1, val);
			}
			
			if(i.arguments[0].equals("R4")){
				mem.set(mem.R4_1, val);
			}
			
			if(i.arguments[0].equals("R5")){
				mem.set(mem.R5_1, val);
			}
			
			if(i.arguments[0].equals("R6")){
				mem.set(mem.R6_1, val);
			}
			
			if(i.arguments[0].equals("R7")){
				mem.set(mem.R7_1, val);
			}
		}
		
		else if(i.name.equals("LJMP")){
			int count = 0;
			
			for(Instruction in : instructionList){
				if(in.name.equals("LABEL")){
					if(in.arguments[0].equals(i.arguments[0])){
						int old = pc;
						pc = count;
						return old;
					}
				}
				
				count++;
			}
		}
		
		else if(i.name.equals("DECACC")){
			mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - 1));
		}
		
		else if(i.name.equals("INCACC")){
			mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + 1));
		}
		
		else if(i.name.equals("INCREGISTER")){
			if(i.arguments[0].equals("R0")){
				mem.mem[mem.R0_1]++;
			}
			
			if(i.arguments[0].equals("R1")){
				mem.mem[mem.R1_1]++;
			}
			
			if(i.arguments[0].equals("R2")){
				mem.mem[mem.R2_1]++;
			}
			
			if(i.arguments[0].equals("R3")){
				mem.mem[mem.R3_1]++;
			}
			
			if(i.arguments[0].equals("R4")){
				mem.mem[mem.R4_1]++;
			}
			
			if(i.arguments[0].equals("R5")){
				mem.mem[mem.R5_1]++;
			}
			
			if(i.arguments[0].equals("R6")){
				mem.mem[mem.R6_1]++;
			}
			
			if(i.arguments[0].equals("R7")){
				mem.mem[mem.R7_1]++;
			}
		}
		
		else if(i.name.equals("DECREGISTER")){
			if(i.arguments[0].equals("R0")){
				mem.mem[mem.R0_1]--;
			}
			
			if(i.arguments[0].equals("R1")){
				mem.mem[mem.R1_1]--;
			}
			
			if(i.arguments[0].equals("R2")){
				mem.mem[mem.R2_1]--;
			}
			
			if(i.arguments[0].equals("R3")){
				mem.mem[mem.R3_1]--;
			}
			
			if(i.arguments[0].equals("R4")){
				mem.mem[mem.R4_1]--;
			}
			
			if(i.arguments[0].equals("R5")){
				mem.mem[mem.R5_1]--;
			}
			
			if(i.arguments[0].equals("R6")){
				mem.mem[mem.R6_1]--;
			}
			
			if(i.arguments[0].equals("R7")){
				mem.mem[mem.R7_1]--;
			}
		}
		
		else if(i.name.equals("COMPLEMENTA")){
			short s = mem.get(mem.ACC);
			String str = Integer.toBinaryString(s);
			String out = "";
			
			while (str.length() < 8) {
				str = "0" + str;
			}
			
			for(int j = 0; j < str.length(); j++){
				if(str.charAt(j) == '0'){
					out = out + "1";
				} else {
					out = out + "0";
				}
			}
			
			int o = Integer.parseInt(out, 2);
			
			mem.set(mem.ACC, (short) o);
			
		}
		
		else if(i.name.equals("ACCANDREG")){
			
			short s1 = mem.mem[memory8051.ACC], s2 = 0;
			
			if(i.arguments[0].equals("R0")){
				s2 = mem.mem[memory8051.R0_1];
			}
			
			if(i.arguments[0].equals("R1")){
				s2 = mem.mem[memory8051.R1_1];
			}
			
			if(i.arguments[0].equals("R2")){
				s2 = mem.mem[memory8051.R2_1];
			}
			
			if(i.arguments[0].equals("R3")){
				s2 = mem.mem[memory8051.R3_1];
			}
			
			if(i.arguments[0].equals("R4")){
				s2 = mem.mem[memory8051.R4_1];
			}
			
			if(i.arguments[0].equals("R5")){
				s2 = mem.mem[memory8051.R5_1];
			}
			
			if(i.arguments[0].equals("R6")){
				s2 = mem.mem[memory8051.R6_1];
			}
			
			if(i.arguments[0].equals("R7")){
				s2 = mem.mem[memory8051.R7_1];
			}
			
			short ss = Utils.and(s1, s2);
			
			mem.set(memory8051.ACC, ss);
		}
		
		else if(i.name.equals("REGANDHEX")){
			
			short s1 = Utils.getValueFromHex(i.arguments[1]), s2 = 0;
			
			if(i.arguments[0].equals("R0")){
				s2 = mem.mem[memory8051.R0_1];
			}
			
			if(i.arguments[0].equals("R1")){
				s2 = mem.mem[memory8051.R1_1];
			}
			
			if(i.arguments[0].equals("R2")){
				s2 = mem.mem[memory8051.R2_1];
			}
			
			if(i.arguments[0].equals("R3")){
				s2 = mem.mem[memory8051.R3_1];
			}
			
			if(i.arguments[0].equals("R4")){
				s2 = mem.mem[memory8051.R4_1];
			}
			
			if(i.arguments[0].equals("R5")){
				s2 = mem.mem[memory8051.R5_1];
			}
			
			if(i.arguments[0].equals("R6")){
				s2 = mem.mem[memory8051.R6_1];
			}
			
			if(i.arguments[0].equals("R7")){
				s2 = mem.mem[memory8051.R7_1];
			}
			
			short ss = Utils.and(s1, s2);
			
			if(i.arguments[0].equals("R0")){
				mem.set(memory8051.R0_1, ss);
			}
			
			if(i.arguments[0].equals("R1")){
				mem.set(memory8051.R1_1, ss);
			}
			
			if(i.arguments[0].equals("R2")){
				mem.set(memory8051.R2_1, ss);
			}
			
			if(i.arguments[0].equals("R3")){
				mem.set(memory8051.R3_1, ss);
			}
			
			if(i.arguments[0].equals("R4")){
				mem.set(memory8051.R4_1, ss);
			}
			
			if(i.arguments[0].equals("R5")){
				mem.set(memory8051.R5_1, ss);
			}
			
			if(i.arguments[0].equals("R6")){
				mem.set(memory8051.R6_1, ss);
			}
			
			if(i.arguments[0].equals("R7")){
				mem.set(memory8051.R7_1, ss);
			}
			
			
		}
		
		else if(i.name.equals("REGANDACC")){
			
			short s1 = mem.get(memory8051.ACC), s2 = 0;
			
			if(i.arguments[0].equals("R0")){
				s2 = mem.mem[memory8051.R0_1];
			}
			
			if(i.arguments[0].equals("R1")){
				s2 = mem.mem[memory8051.R1_1];
			}
			
			if(i.arguments[0].equals("R2")){
				s2 = mem.mem[memory8051.R2_1];
			}
			
			if(i.arguments[0].equals("R3")){
				s2 = mem.mem[memory8051.R3_1];
			}
			
			if(i.arguments[0].equals("R4")){
				s2 = mem.mem[memory8051.R4_1];
			}
			
			if(i.arguments[0].equals("R5")){
				s2 = mem.mem[memory8051.R5_1];
			}
			
			if(i.arguments[0].equals("R6")){
				s2 = mem.mem[memory8051.R6_1];
			}
			
			if(i.arguments[0].equals("R7")){
				s2 = mem.mem[memory8051.R7_1];
			}
			
			short ss = Utils.and(s1, s2);
			
			if(i.arguments[0].equals("R0")){
				mem.set(memory8051.R0_1, ss);
			}
			
			if(i.arguments[0].equals("R1")){
				mem.set(memory8051.R1_1, ss);
			}
			
			if(i.arguments[0].equals("R2")){
				mem.set(memory8051.R2_1, ss);
			}
			
			if(i.arguments[0].equals("R3")){
				mem.set(memory8051.R3_1, ss);
			}
			
			if(i.arguments[0].equals("R4")){
				mem.set(memory8051.R4_1, ss);
			}
			
			if(i.arguments[0].equals("R5")){
				mem.set(memory8051.R5_1, ss);
			}
			
			if(i.arguments[0].equals("R6")){
				mem.set(memory8051.R6_1, ss);
			}
			
			if(i.arguments[0].equals("R7")){
				mem.set(memory8051.R7_1, ss);
			}
			
			
		}
		
		else if(i.name.equals("REGORACC")){
			
			short s1 = mem.get(memory8051.ACC), s2 = 0;
			
			if(i.arguments[0].equals("R0")){
				s2 = mem.mem[memory8051.R0_1];
			}
			
			if(i.arguments[0].equals("R1")){
				s2 = mem.mem[memory8051.R1_1];
			}
			
			if(i.arguments[0].equals("R2")){
				s2 = mem.mem[memory8051.R2_1];
			}
			
			if(i.arguments[0].equals("R3")){
				s2 = mem.mem[memory8051.R3_1];
			}
			
			if(i.arguments[0].equals("R4")){
				s2 = mem.mem[memory8051.R4_1];
			}
			
			if(i.arguments[0].equals("R5")){
				s2 = mem.mem[memory8051.R5_1];
			}
			
			if(i.arguments[0].equals("R6")){
				s2 = mem.mem[memory8051.R6_1];
			}
			
			if(i.arguments[0].equals("R7")){
				s2 = mem.mem[memory8051.R7_1];
			}
			
			short ss = Utils.or(s1, s2);
			
			if(i.arguments[0].equals("R0")){
				mem.set(memory8051.R0_1, ss);
			}
			
			if(i.arguments[0].equals("R1")){
				mem.set(memory8051.R1_1, ss);
			}
			
			if(i.arguments[0].equals("R2")){
				mem.set(memory8051.R2_1, ss);
			}
			
			if(i.arguments[0].equals("R3")){
				mem.set(memory8051.R3_1, ss);
			}
			
			if(i.arguments[0].equals("R4")){
				mem.set(memory8051.R4_1, ss);
			}
			
			if(i.arguments[0].equals("R5")){
				mem.set(memory8051.R5_1, ss);
			}
			
			if(i.arguments[0].equals("R6")){
				mem.set(memory8051.R6_1, ss);
			}
			
			if(i.arguments[0].equals("R7")){
				mem.set(memory8051.R7_1, ss);
			}
			
			
		}
		
		else if(i.name.equals("ACCORREG")){
			
			short s1 = mem.mem[memory8051.ACC], s2 = 0;
			
			if(i.arguments[0].equals("R0")){
				s2 = mem.mem[memory8051.R0_1];
			}
			
			if(i.arguments[0].equals("R1")){
				s2 = mem.mem[memory8051.R1_1];
			}
			
			if(i.arguments[0].equals("R2")){
				s2 = mem.mem[memory8051.R2_1];
			}
			
			if(i.arguments[0].equals("R3")){
				s2 = mem.mem[memory8051.R3_1];
			}
			
			if(i.arguments[0].equals("R4")){
				s2 = mem.mem[memory8051.R4_1];
			}
			
			if(i.arguments[0].equals("R5")){
				s2 = mem.mem[memory8051.R5_1];
			}
			
			if(i.arguments[0].equals("R6")){
				s2 = mem.mem[memory8051.R6_1];
			}
			
			if(i.arguments[0].equals("R7")){
				s2 = mem.mem[memory8051.R7_1];
			}
			
			short ss = Utils.or(s1, s2);
			
			mem.set(memory8051.ACC, ss);
		}
		
		else if(i.name.equals("REGORHEX")){
			
			short s1 = Utils.getValueFromHex(i.arguments[1]), s2 = 0;
			
			if(i.arguments[0].equals("R0")){
				s2 = mem.mem[memory8051.R0_1];
			}
			
			if(i.arguments[0].equals("R1")){
				s2 = mem.mem[memory8051.R1_1];
			}
			
			if(i.arguments[0].equals("R2")){
				s2 = mem.mem[memory8051.R2_1];
			}
			
			if(i.arguments[0].equals("R3")){
				s2 = mem.mem[memory8051.R3_1];
			}
			
			if(i.arguments[0].equals("R4")){
				s2 = mem.mem[memory8051.R4_1];
			}
			
			if(i.arguments[0].equals("R5")){
				s2 = mem.mem[memory8051.R5_1];
			}
			
			if(i.arguments[0].equals("R6")){
				s2 = mem.mem[memory8051.R6_1];
			}
			
			if(i.arguments[0].equals("R7")){
				s2 = mem.mem[memory8051.R7_1];
			}
			
			short ss = Utils.or(s1, s2);
			
			if(i.arguments[0].equals("R0")){
				mem.set(memory8051.R0_1, ss);
			}
			
			if(i.arguments[0].equals("R1")){
				mem.set(memory8051.R1_1, ss);
			}
			
			if(i.arguments[0].equals("R2")){
				mem.set(memory8051.R2_1, ss);
			}
			
			if(i.arguments[0].equals("R3")){
				mem.set(memory8051.R3_1, ss);
			}
			
			if(i.arguments[0].equals("R4")){
				mem.set(memory8051.R4_1, ss);
			}
			
			if(i.arguments[0].equals("R5")){
				mem.set(memory8051.R5_1, ss);
			}
			
			if(i.arguments[0].equals("R6")){
				mem.set(memory8051.R6_1, ss);
			}
			
			if(i.arguments[0].equals("R7")){
				mem.set(memory8051.R7_1, ss);
			}
			
			
		}
		
		else if(i.name.equals("ADDTOACCFROMREG")){
			if(i.arguments[0].equals("R0")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + mem.mem[memory8051.R0_1]));
			}
			
			if(i.arguments[0].equals("R1")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + mem.mem[memory8051.R1_1]));
			}
			
			if(i.arguments[0].equals("R2")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + mem.mem[memory8051.R2_1]));
			}
			
			if(i.arguments[0].equals("R3")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + mem.mem[memory8051.R3_1]));
			}
			
			if(i.arguments[0].equals("R4")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + mem.mem[memory8051.R4_1]));
			}
			if(i.arguments[0].equals("R5")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + mem.mem[memory8051.R5_1]));
			}
			if(i.arguments[0].equals("R6")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + mem.mem[memory8051.R6_1]));
			}
			if(i.arguments[0].equals("R7")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + mem.mem[memory8051.R7_1]));
			}
		}
		
		else if(i.name.equals("ADDTOACCHEX")){
			mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] + Utils.getValueFromHex(i.arguments[0])));
		}
		
		else if(i.name.equals("SUBSTRACTREGFROMACC")){
			if(i.arguments[0].equals("R0")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - mem.mem[memory8051.R0_1]));
			}
			
			if(i.arguments[0].equals("R1")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - mem.mem[memory8051.R1_1]));
			}
			
			if(i.arguments[0].equals("R2")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - mem.mem[memory8051.R2_1]));
			}
			
			if(i.arguments[0].equals("R3")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - mem.mem[memory8051.R3_1]));
			}
			
			if(i.arguments[0].equals("R4")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - mem.mem[memory8051.R4_1]));
			}
			if(i.arguments[0].equals("R5")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - mem.mem[memory8051.R5_1]));
			}
			if(i.arguments[0].equals("R6")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - mem.mem[memory8051.R6_1]));
			}
			if(i.arguments[0].equals("R7")){
				mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - mem.mem[memory8051.R7_1]));
			}
			
		}
		
		else if(i.name.equals("SUBSTRACTHEXFROMACC")){
			mem.set(memory8051.ACC, (short) (mem.mem[memory8051.ACC] - Utils.getValueFromHex(i.arguments[0])));
		}
		
		return pc++;
	}
}